#pragma once

#include <string>
#include <map>
#include <vector>
#include <gvc.h>
#include <QRect>
#include <QString>

/// A struct containing the information for a GVGraph's node
struct GVNode
{
	/// The unique identifier of the node in the graph
	QString name;

	/// The position of the center point of the node from the top-left corner
	double x, y;

	/// The size of the node in pixels
	double height, width;
};

/// A struct containing the information for a GVGraph's edge
struct GVEdge
{
	/// The source and target nodes of the edge
	QString source;
	QString target;

	/// Path of the edge's line
	//QPainterPath path;
};

//! An object containing a Graphviz graph and its associated nodes and edges
class GVGraph
{
public:
	//! Default DPI value used by dot (which uses points instead of pixels
	//! for coordinates). Dot uses a 72 DPI value for converting it's position 
	//! coordinates from points to pixels while we display at 96 DPI on most 
	//! operating systems.
	static const int DotDefaultDPI = 72;
	
	/*!
	 * \brief Construct a Graphviz graph object.
	 * \param name The name of the graph, must be unique in the application.
	 * \param node_size The size in pixels of each node.
	 */
	GVGraph(const QString& name, double node_size=50);
	~GVGraph();

	/// Add and remove nodes
	void addNode(const QString& name, int width, int height);
	void removeNode(const QString& name);
	void clearNodes();
	bool containsNode(const QString& name);

	/// Add and remove edges
	void addEdge(const QString& source, const QString& target);
	void removeEdge(const QString& source, const QString& target);
	void removeEdge(const std::pair<const QString&, const QString&>& key);
	bool containsEdge(const QString& source, const QString& target);
	bool containsEdge(const std::pair<const QString&, const QString&>& key);
	
	bool setRootNode(const QString& name);
	void applyLayout();
	QRectF boundingRect() const;

	/// Set the font to use in all the labels
	//void setFont(QFont font);

	std::vector<GVNode> nodes() const;

	std::vector<GVEdge> edges() const;
private:
	GVC_t *_context;
	Agraph_t *_graph;
	//QFont _font;
	typedef std::map<QString, Agnode_t*> NodesVector;
	NodesVector _nodes;
	typedef std::map<std::pair<QString, QString>, Agedge_t*> EdgesVector;
	EdgesVector _edges;
	double getDpi() const;
};
